]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
search: Make the internal search interface callback-based
authorJasper St. Pierre <jstpierre@mecheye.net>
Sat, 2 Nov 2013 23:45:35 +0000 (19:45 -0400)
committerJasper St. Pierre <jstpierre@mecheye.net>
Sun, 3 Nov 2013 00:07:06 +0000 (20:07 -0400)
Long ago, the search system worked in a synchronous manner: providers
were given a query, and results were collected in a single array of
[provider, results] pairs, and then the search display was updated
from that.

We introduced an asynchronous search system when we wanted to potentially
add a Zeitgeist search provider to the Shell in 3.2. For a while, search
providers were either async or sync, which worked by storing a dummy array
in the results, and adding a method for search providers to add results
later.

Later, we removed the search system entirely and ported the remaining
search providers to simply use the API to modify the empty array, but the
remains of the synchronous search system with its silly array still
lingered.

Finally, it's time to modernize. Promises^WCallbacks are the future.

Port the one remaining in-shell search engine (app search) to the new
callback based system, and simplify the remote search system in the
process.

js/ui/appDisplay.js
js/ui/remoteSearch.js
js/ui/search.js

index 7186d9f3d0a01f1a0999a36ab15eca95342aec73..0e924323802e02e0759ad8b9cb56648dd5775c6d 100644 (file)
@@ -890,12 +890,12 @@ const AppSearchProvider = new Lang.Class({
         return results.slice(0, maxNumber);
     },
 
-    getInitialResultSet: function(terms) {
-        this.searchSystem.setResults(this, this._appSys.initial_search(terms));
+    getInitialResultSet: function(terms, callback, cancellable) {
+        callback(this._appSys.initial_search(terms));
     },
 
-    getSubsearchResultSet: function(previousResults, terms) {
-        this.searchSystem.setResults(this, this._appSys.subsearch(previousResults, terms));
+    getSubsearchResultSet: function(terms, callback, cancellable) {
+        callbacl(this._appSys.subsearch(previousResults, terms));
     },
 
     activateResult: function(result) {
index 520d109abe318113515b2454f9d678975b765ce0..e21416e06cf43f38b4be0e6db8e51c2842279e9a 100644 (file)
@@ -203,8 +203,6 @@ const RemoteSearchProvider = new Lang.Class({
         this.appInfo = appInfo;
         this.id = appInfo.get_id();
         this.isRemoteProvider = true;
-
-        this._cancellable = new Gio.Cancellable();
     },
 
     createIcon: function(size, meta) {
@@ -234,29 +232,27 @@ const RemoteSearchProvider = new Lang.Class({
         return regularResults.slice(0, maxNumber).concat(specialResults.slice(0, maxNumber));
     },
 
-    _getResultsFinished: function(results, error) {
+    _getResultsFinished: function(results, error, callback) {
         if (error) {
             if (!error.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
                 log('Received error from DBus search provider %s: %s'.format(this.id, String(error)));
-        } else {
-            this.searchSystem.setResults(this, results[0]);
+            callback([]);
+            return;
         }
+
+        callback(results[0]);
     },
 
-    getInitialResultSet: function(terms) {
-        this._cancellable.cancel();
-        this._cancellable.reset();
+    getInitialResultSet: function(terms, callback, cancellable) {
         this.proxy.GetInitialResultSetRemote(terms,
-                                             Lang.bind(this, this._getResultsFinished),
-                                             this._cancellable);
+                                             Lang.bind(this, this._getResultsFinished, callback),
+                                             cancellable);
     },
 
-    getSubsearchResultSet: function(previousResults, newTerms) {
-        this._cancellable.cancel();
-        this._cancellable.reset();
+    getSubsearchResultSet: function(previousResults, newTerms, cancellable) {
         this.proxy.GetSubsearchResultSetRemote(previousResults, newTerms,
-                                               Lang.bind(this, this._getResultsFinished),
-                                               this._cancellable);
+                                               Lang.bind(this, this._getResultsFinished, callback),
+                                               cancellable);
     },
 
     _getResultMetasFinished: function(results, error, callback) {
@@ -284,12 +280,10 @@ const RemoteSearchProvider = new Lang.Class({
         callback(resultMetas);
     },
 
-    getResultMetas: function(ids, callback) {
-        this._cancellable.cancel();
-        this._cancellable.reset();
+    getResultMetas: function(ids, callback, cancellable) {
         this.proxy.GetResultMetasRemote(ids,
                                         Lang.bind(this, this._getResultMetasFinished, callback),
-                                        this._cancellable);
+                                        cancellable);
     },
 
     activateResult: function(id) {
index b55b76a94784dd77b03893d6781731a978d6bd6f..1b2953a9875726886b400b325d043928713119d3 100644 (file)
@@ -37,6 +37,8 @@ const SearchSystem = new Lang.Class({
         this._searchSettings.connect('changed::sort-order', Lang.bind(this, this._reloadRemoteProviders));
 
         this._reloadRemoteProviders();
+
+        this._cancellable = new Gio.Cancellable();
     },
 
     addProvider: function(provider) {
@@ -60,14 +62,12 @@ const SearchSystem = new Lang.Class({
     },
 
     _registerProvider: function (provider) {
-        provider.searchSystem = this;
         this._providers.push(provider);
     },
 
     _unregisterProvider: function (provider) {
         let index = this._providers.indexOf(provider);
         this._providers.splice(index, 1);
-        provider.searchSystem = null;
     },
 
     getProviders: function() {
@@ -75,54 +75,50 @@ const SearchSystem = new Lang.Class({
     },
 
     getTerms: function() {
-        return this._previousTerms;
+        return this._terms;
     },
 
     reset: function() {
-        this._previousTerms = [];
-        this._previousResults = [];
+        this._terms = [];
+        this._results = {};
     },
 
-    setResults: function(provider, results) {
-        let i = this._providers.indexOf(provider);
-        if (i == -1)
-            return;
-
-        this._previousResults[i] = [provider, results];
-        this.emit('search-updated', this._previousResults[i]);
+    _gotResults: function(results, provider) {
+        this._results[provider.id] = results;
+        this.emit('search-updated', provider, results);
     },
 
     setTerms: function(terms) {
+        this._cancellable.cancel();
+        this._cancellable.reset();
+
+        let previousResults = this._results;
+        let previousTerms = this._terms;
+        this.reset();
+
         if (!terms)
             return;
 
         let searchString = terms.join(' ');
-        let previousSearchString = this._previousTerms.join(' ');
+        let previousSearchString = previousTerms.join(' ');
         if (searchString == previousSearchString)
             return;
 
         let isSubSearch = false;
-        if (this._previousTerms.length > 0)
+        if (previousTerms.length > 0)
             isSubSearch = searchString.indexOf(previousSearchString) == 0;
 
-        let previousResultsArr = this._previousResults;
-
-        let results = [];
-        this._previousTerms = terms;
-        this._previousResults = results;
+        this._terms = terms;
 
         if (isSubSearch) {
-            for (let i = 0; i < this._providers.length; i++) {
-                let [provider, previousResults] = previousResultsArr[i];
-                results.push([provider, []]);
-                provider.getSubsearchResultSet(previousResults, terms);
-            }
+            this._providers.forEach(Lang.bind(this, function(provider) {
+                let previousResults = previousResults[provider.id];
+                provider.getSubsearchResultSet(previousResults, terms, Lang.bind(this, this._gotResults, provider), this._cancellable);
+            }));
         } else {
-            for (let i = 0; i < this._providers.length; i++) {
-                let provider = this._providers[i];
-                results.push([provider, []]);
-                provider.getInitialResultSet(terms);
-            }
+            this._providers.forEach(Lang.bind(this, function(provider) {
+                provider.getInitialResultSet(terms, Lang.bind(this, this._gotResults, provider), this._cancellable);
+            }));
         }
     }
 });
@@ -309,6 +305,8 @@ const SearchResultsBase = new Lang.Class({
         this.actor.add(separator.actor);
 
         this._resultDisplays = {};
+
+        this._cancellable = new Gio.Cancellable();
     },
 
     destroy: function() {
@@ -345,6 +343,9 @@ const SearchResultsBase = new Lang.Class({
         if (metasNeeded.length === 0) {
             callback();
         } else {
+            this._cancellable.cancel();
+            this._cancellable.reset();
+
             this.provider.getResultMetas(metasNeeded, Lang.bind(this, function(metas) {
                 metasNeeded.forEach(Lang.bind(this, function(resultId, i) {
                     let meta = metas[i];
@@ -354,7 +355,7 @@ const SearchResultsBase = new Lang.Class({
                     this._resultDisplays[resultId] = display;
                 }));
                 callback();
-            }));
+            }), this._cancellable);
         }
     },
 
@@ -638,12 +639,11 @@ const SearchResults = new Lang.Class({
         }
     },
 
-    _updateResults: function(searchSystem, results) {
+    _updateResults: function(searchSystem, provider, results) {
         let terms = searchSystem.getTerms();
-        let [provider, providerResults] = results;
         let display = provider.display;
 
-        display.updateSearch(providerResults, terms, Lang.bind(this, function() {
+        display.updateSearch(results, terms, Lang.bind(this, function() {
             this._maybeSetInitialSelection();
             this._updateStatusText();
         }));